<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        Function.prototype.myCall = function (context,...arg){
            /*
                call的调用方法fn.call(context)
                在这个函数中,可以通过this拿到fn
                目标:调用fn 把fn的this指向context,返回fn的返回值
            */

            //不同数据类型进行调用,其this指向不一样
            if(context === null || context === undefined ){
                context = window
            }

            if(typeof context !== "object" && typeof context !== "function"){
                //如果第一个参数是非null undefined 对象,则需要包装成对象
                context = Object(context)
            }

            //其他情况均适用通用设定,调用fn并返回fn的返回值
            /*
            可以通过给对象扩展属性的方式来实现,
            如果扩展的属性和对象自身的属性重名,会发生覆盖操作,
            为了避免覆盖操作,需使用symbol来扩展属性
            */
           const sy1 = Symbol("sy1")
           context[sy1] = this

           //调用这个扩展方法,context新增的属性所代表的fn就会被调用,并把this指向context,同时接收fn的返回值
           const re = context[sy1](...arg)
           //用完这个属性就删掉,不会对原始的context产生任何影响
           delete context[sy1]

           return re

        }

        function fn(a,b) {
            console.log(this,a+b);
            return 1
        }

        console.log(fn.myCall({},1,2));


       
    </script>
</body>
</html>